package com.mlethe.library.socialtool.core;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import androidx.annotation.NonNull;

import com.alipay.sdk.app.AuthTask;
import com.alipay.sdk.app.H5PayCallback;
import com.alipay.sdk.app.PayTask;
import com.alipay.sdk.util.H5PayResultModel;
import com.alipay.share.sdk.openapi.APAPIFactory;
import com.alipay.share.sdk.openapi.IAPApi;
import com.mlethe.library.socialtool.callback.OauthActionListener;
import com.mlethe.library.socialtool.callback.PayActionListener;
import com.mlethe.library.socialtool.entity.AliPayResult;
import com.mlethe.library.socialtool.entity.AuthResult;

import org.json.JSONObject;

import java.net.URLEncoder;
import java.util.Map;

/**
 * 支付宝登录、支付
 *
 * @author Mlethe
 */
public class Alipay implements Oauth<IAPApi> {

    private Handler mHandler;

    private Context mContext;

    private final String mPid;
    private final String mAppid;

    private final String mRsa2Private;

    private IAPApi mApi;

    private OauthActionListener mOauthListener;
    private PayActionListener mPayListener;

    /**
     * @param context
     * @param appid       支付宝 AppId
     * @param pid         支付宝账户登录授权业务的入参 pid
     * @param rsa2Private pkcs8 格式的商户私钥。
     */
    public Alipay(Context context, String appid, String pid, String rsa2Private) {
        this.mContext = context;
        this.mPid = pid;
        this.mAppid = appid;
        this.mRsa2Private = rsa2Private;
        mHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                Alipay.this.handleMessage(msg);
            }
        };
    }

    @Override
    public IAPApi getApi() {
        if (mApi == null) {
            this.mApi = APAPIFactory.createZFBApi(mContext.getApplicationContext(), mAppid, false);
        }
        return mApi;
    }

    /**
     * 授权登录回调
     * 请在调用 oauth() 方法前调用
     *
     * @param listener listener
     * @return
     */
    public Alipay setOauthActionListener(OauthActionListener listener) {
        this.mOauthListener = listener;
        return this;
    }

    /**
     * 支付回调
     * 请在调用 pay() 方法前调用
     *
     * @param listener listener
     * @return
     */
    public Alipay setPayActionListener(PayActionListener listener) {
        this.mPayListener = listener;
        return this;
    }

    /**
     * H5唤起支付宝支付
     *
     * @param activity
     * @param url      支付URL
     * @return true：表示URL为支付宝支付URL，URL已经被拦截并支付转化；false：表示URL非支付宝支付URL；
     */
    public boolean payUrl(final Activity activity, String url) {
        if (!isAppInstalled()) {
            if (mPayListener != null) {
                mPayListener.onNotInstalled(Platform.ALIPAY);
                mPayListener = null;
            }
            return false;
        }
        PayTask payTask = new PayTask(activity);
        boolean isIntercepted = payTask.payInterceptorWithUrl(url, true, new H5PayCallback() {
            @Override
            public void onPayResult(H5PayResultModel h5PayResultModel) {
                Message message = new Message();
                message.what = 3;
                message.obj = h5PayResultModel;
                mHandler.sendMessage(message);
            }
        });
        return isIntercepted;
    }

    /**
     * 二维码链接唤起支付(没有支付成功、失败回调)
     * @param qrcode 二维码链接
     */
    public void pay(String qrcode) {
        if (!isAppInstalled()) {
            if (mPayListener != null) {
                mPayListener.onNotInstalled(Platform.ALIPAY);
                mPayListener = null;
            }
            return;
        }
        try {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            Uri uri = Uri.parse("alipays://platformapi/startapp?saId=10000007&qrcode=" + URLEncoder.encode(qrcode, "UTF-8"));
            intent.setData(uri);
            mContext.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            if (mPayListener != null) {
                mPayListener.onFail(Platform.ALIPAY);
                mPayListener = null;
            }
        }
    }

    /**
     * 调起支付宝支付
     *
     * @param activity
     * @param orderInfo 订单信息（"alipay_sdk=alipay-sdk-java-3.7.4.ALL&app_id=2016101000649179&biz_content={\"body\":\"我是测试数据\",\"out_trade_no\":\"20190730\",\"product_code\":\"QUICK_MSECURITY_PAY\",\"subject\":\"App支付测试Java\",\"timeout_express\":\"30m\",\"total_amount\":\"0.01\"}&charset=utf-8&format=json&method=alipay.trade.app.pay&sign=Z+etI84SIyhKOMzKVWDsGK0uAG+cn3O476zvwdVKMdiblkAIvhIUseeGoqvyLnsKxP62aW5J3D5s258kJQWfyHt7wA/b0jL8oe8i9LjAjrOTZFuX2AIkKa2TbyX96uQt2BY5oFDS6W564QOxL+0QqA1GqfsInaBKaJiuBZFhJ5924Wh4BnHS3X6abetAKyCVp+2oVI1NAuq7CwcILHS59YhhGfim6lMgbyVi7Y2o/s/UYpY03nzpL6FXqhZz87mxWXvxCgSZkUgDfzleVf3pQgtSNKjDCR5OIVAZHw+QlrrabDI7Hglbc9syZmSNUlgYzzqyownkLAk7vEzKY35lmQ==&sign_type=RSA2×tamp=2019-07-30 16:04:16&version=1.0"）
     */
    public void pay(final Activity activity, final String orderInfo) {
        if (!isAppInstalled()) {
            if (mPayListener != null) {
                mPayListener.onNotInstalled(Platform.ALIPAY);
                mPayListener = null;
            }
            return;
        }
        final Runnable payRunnable = new Runnable() {
            @Override
            public void run() {
                PayTask alipay = new PayTask(activity);
                Map<String, String> result = alipay.payV2(orderInfo, true);
                if (mHandler == null) {
                    return;
                }
                Message message = new Message();
                message.what = 2;
                message.obj = result;
                mHandler.sendMessage(message);
            }
        };
        // 必须异步调用
        Thread payThread = new Thread(payRunnable);
        payThread.start();
    }

    /**
     * 支付宝授权登录 （isShowLoading设置为 true ）
     *
     * @param activity
     * @param authInfo 授权信息串
     */
    public void oauth(Activity activity, String authInfo) {
        oauth(activity, true, authInfo);
    }

    /**
     * 支付宝授权登录(完整版)
     *
     * @param activity
     * @param isShowLoading 是否需要在授权开始时展示一个 loading 界面。无特殊需要时设置为 true 即可。
     * @param authInfo      授权信息串（"apiname=com.alipay.account.auth&app_id=xxxxx&app_name=mc&auth_type=AUTHACCOUNT&biz_type=openservice&method=alipay.open.auth.sdk.code.get&pid=xxxxx&product_id=APP_FAST_LOGIN&scope=kuaijie&sign_type=RSA2&target_id=20141225xxxx&sign=fMcp4GtiM6rxSIeFnJCVePJKV43eXrUP86CQgiLhDHH2u/dN75eEvmywc2ulkm7qKRetkU9fbVZtJIqFdMJcJ9Yp+JI/F/pESafFR6rB2fRjiQQLGXvxmDGVMjPSxHxVtIqpZy5FDoKUSjQ2/ILDKpu3/+tAtm2jRw1rUoMhgt0="）
     */
    public void oauth(final Activity activity, final boolean isShowLoading, final String authInfo) {
        if (!isAppInstalled()) {
            if (mOauthListener != null) {
                mOauthListener.onNotInstalled(Platform.ALIPAY);
                mOauthListener = null;
            }
            return;
        }
        Runnable authRunnable = new Runnable() {
            @Override
            public void run() {
                // 构造AuthTask 对象
                AuthTask authTask = new AuthTask(activity);
                // 调用授权接口，获取授权结果
                Map<String, String> result = authTask.authV2(authInfo, isShowLoading);
                if (mHandler == null) {
                    return;
                }
                Message message = new Message();
                message.what = 1;
                message.obj = result;
                mHandler.sendMessage(message);
            }
        };
        // 必须异步调用
        Thread authThread = new Thread(authRunnable);
        authThread.start();
    }

    /**
     * 支付宝授权登录(完整版)
     *
     * @param activity
     * @param isShowLoading 是否需要在授权开始时展示一个 loading 界面。无特殊需要时设置为 true 即可。
     */
    public void oauth(final Activity activity, boolean isShowLoading) {
        Map<String, String> authInfoMap = AlipayUtil.buildAuthInfoMap(mAppid, mPid);
        oauth(activity, isShowLoading, AlipayUtil.getSign(authInfoMap, mRsa2Private));
    }

    /**
     * 支付宝授权登录(完整版)
     *
     * @param activity
     */
    public void oauth(final Activity activity) {
        oauth(activity, true);
    }

    /**
     * 判断是否安装支付宝
     *
     * @return
     */
    @Override
    public boolean isAppInstalled() {
        if (getApi() == null || !getApi().isZFBAppInstalled()) {
            return false;
        }
        return true;
    }

    /**
     * 判断版本是否大于9.9.5版本
     *
     * @return true 9.9.5版本及以上，false 9.9.5版本以下
     */
    public boolean isAlipayIgnoreChannel() {
        return getApi().getZFBVersionCode() >= 101;
    }

    /**
     * 消息处理
     *
     * @param msg
     */
    private final void handleMessage(Message msg) {
        try {
            if (msg.what == 1) {
                // 授权登录
                Map<String, String> result = (Map<String, String>) msg.obj;
                final AuthResult authResult = new AuthResult(result, true);
                if (mOauthListener == null) {
                    return;
                }
                if (authResult.getResultStatus() == 9000) {
                    if (authResult.getResultCode() == 200) {
                        // 授权成功
                        mOauthListener.onComplete(Platform.ALIPAY, null);
                    } else if (authResult.getResultStatus() == 1005) {
                        // 账户已冻结
                        mOauthListener.onFail(Platform.ALIPAY);
                    } else if (authResult.getResultStatus() == 202) {
                        // 系统异常
                        mOauthListener.onFail(Platform.ALIPAY);
                    } else {
                        // 未知错误
                        mOauthListener.onFail(Platform.ALIPAY);
                    }
                } else if (authResult.getResultStatus() == 4000) {
                    // 系统异常
                    mOauthListener.onFail(Platform.ALIPAY);
                } else if (authResult.getResultStatus() == 6001) {
                    // 用户中途取消
                    mOauthListener.onCancel(Platform.ALIPAY);
                } else if (authResult.getResultStatus() == 6002) {
                    // 网络连接出错
                    mOauthListener.onFail(Platform.ALIPAY);
                } else {
                    // 未知错误
                    mOauthListener.onFail(Platform.ALIPAY);
                }
                mOauthListener = null;
            } else if (msg.what == 2) {
                // 支付
                Map<String, String> result = (Map<String, String>) msg.obj;
                final AliPayResult payResult = new AliPayResult(result);
                if (mPayListener == null) {
                    return;
                }
                if (payResult.getResultStatus() == 9000) {
                    // 订单支付成功
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("memo", payResult.getMemo());
                    jsonObject.put("result", payResult.getResult());
                    mPayListener.onComplete(Platform.ALIPAY, jsonObject);
                } else if (payResult.getResultStatus() == 8000) {
                    // 正在处理中，支付结果未知（有可能已经支付成功），请查询商户订单列表中订单的支付状态
                    mPayListener.onFail(Platform.ALIPAY);
                } else if (payResult.getResultStatus() == 4000) {
                    // 订单支付失败
                    mPayListener.onFail(Platform.ALIPAY);
                } else if (payResult.getResultStatus() == 5000) {
                    // 重复请求
                    mPayListener.onFail(Platform.ALIPAY);
                } else if (payResult.getResultStatus() == 6001) {
                    // 用户中途取消
                    mPayListener.onCancel(Platform.ALIPAY);
                } else if (payResult.getResultStatus() == 6002) {
                    // 网络连接出错
                    mPayListener.onFail(Platform.ALIPAY);
                } else if (payResult.getResultStatus() == 6004) {
                    // 支付结果未知（有可能已经支付成功），请查询商户订单列表中订单的支付状态
                    mPayListener.onFail(Platform.ALIPAY);
                } else {
                    // 其它支付错误
                    mPayListener.onFail(Platform.ALIPAY);
                }
                mPayListener = null;
            } else if (msg.what == 3) {
                // H5唤起支付
                H5PayResultModel result = (H5PayResultModel) msg.obj;
                int resultCode = Integer.valueOf(result.getResultCode());
                if (mPayListener == null) {
                    return;
                }
                if (resultCode == 9000) {
                    // 订单支付成功
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("returnUrl", result.getReturnUrl());
                    mPayListener.onComplete(Platform.ALIPAY, jsonObject);
                } else if (resultCode == 8000) {
                    // 正在处理中，支付结果未知（有可能已经支付成功），请查询商户订单列表中订单的支付状态
                    mPayListener.onFail(Platform.ALIPAY);
                } else if (resultCode == 4000) {
                    // 订单支付失败
                    mPayListener.onFail(Platform.ALIPAY);
                } else if (resultCode == 5000) {
                    // 重复请求
                    mPayListener.onFail(Platform.ALIPAY);
                } else if (resultCode == 6001) {
                    // 用户中途取消
                    mPayListener.onCancel(Platform.ALIPAY);
                } else if (resultCode == 6002) {
                    // 网络连接出错
                    mPayListener.onFail(Platform.ALIPAY);
                } else if (resultCode == 6004) {
                    // 支付结果未知（有可能已经支付成功），请查询商户订单列表中订单的支付状态
                    mPayListener.onFail(Platform.ALIPAY);
                } else {
                    // 其它支付错误
                    mPayListener.onFail(Platform.ALIPAY);
                }
                mPayListener = null;
            }
        } catch (Exception e) {
            mOauthListener = null;
            mPayListener = null;
            e.printStackTrace();
        }
    }

    /**
     * 取消注册
     */
    @Override
    public void unregister() {
        mApi = null;
    }

    /**
     * 释放内存
     */
    @Override
    public void release() {
        unregister();
        mContext = null;
        mHandler = null;
        mOauthListener = null;
        mPayListener = null;
    }
}
